﻿/* Original Author:  Dominick O'Dierno odiernod@gmail.com  http://www.odierno.com
 * Date: 5/13/2008   odiernod@gmail.com     --Originally intended for use with DOMercury:  http://www.odierno.com/domercury
 * Description: This Manager class handles the caching of visible Top level system windows.  System Window retrieving used to be
 * done in realtime on search call, and would take several hundred milliseconds to do.  This caches the results once a second and 
 * virtually eliminates any delay in retrieving system windows.
 * 
 * --CHANGELOG--
 * 
 * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DOMercury.Items;
using DOMercury.Interfaces;
using ManagedWinapi.Windows;

namespace DOMercury.Managers
{
    public class SystemWindowManager
    {
        private static int sysWinCount = 0;
        private static System.ComponentModel.BackgroundWorker sysWinCacher;

        private static List<IItemContainer> sysWinCache;

        public static void Initialize()
        {
            sysWinCache = new List<IItemContainer>();
            
            sysWinCacher = new System.ComponentModel.BackgroundWorker();
            sysWinCacher.WorkerSupportsCancellation = true;
            sysWinCacher.DoWork += new System.ComponentModel.DoWorkEventHandler(sysWinCacher_DoWork);
            sysWinCacher.RunWorkerAsync();
        }
        
        public static void Dispose()
        {
            try
            {
                sysWinCacher.CancelAsync();
            }
            catch { }
        }

        static void sysWinCacher_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            CheckForReCache();
        }

        private static void UpdateCache()
        {
            lock (sysWinCache)
            {
                sysWinCache.Clear();
                foreach (SystemWindow w in FilteredWindows)
                {
                    try
                    {
                        sysWinCache.Add(IndexManager.NewIItemContainerwPriority(new SystemWindowItem(w.Title, w.HWnd, w.Process, w.ClassName), false, false));
                    }
                    catch { }
                }
            }
        }

        private static SystemWindow[] FilteredWindows
        {
            get
            {
                return SystemWindow.FilterToplevelWindows(
                            delegate(ManagedWinapi.Windows.SystemWindow c)
                            {
                                return c.Visible;
                            });
            }
        }

        private static void CheckForReCache()
        {
            int newCount;
            while (true)
            {
                newCount = FilteredWindows.Length;
                if (sysWinCount != newCount)
                {
                    sysWinCount = newCount;
                    UpdateCache();
                }
                System.Threading.Thread.Sleep(900);
            }
        }

        public static List<IItemContainer> SystemWindows
        {
            get
            {
                if (sysWinCache != null)
                {
                    return sysWinCache;
                }
                else
                {
                    return new List<IItemContainer>();
                }
            }
        }
        
    }
}
